﻿using Api.Common;
using AppManager.Model;
using PushManager.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Transactions;
using System.Web;

namespace AppManager.BLL
{
    public class ProjectBLL : BaseBLL<Project>
    {
        public static void AddOrUpdate(AddProjectModel model)
        {
            var request = HttpContext.Current.Request;
            var server = HttpContext.Current.Server;
            string appName = model.AppName;
            if (string.IsNullOrEmpty(appName))
            {
                throw new Exception("請輸入項目名稱！");
            }

            string certUrl = SaveFile("CertUrl", request, server, appName);
            string sandBox_CertUrl = SaveFile("sandbox_certUrl", request, server, appName);
            string oldcertUrl = string.Empty, oldSandBox_CertUrl = string.Empty;

            //利用appname獲取project
            var project = GetModel(s => s.Identity == model.AppName);
            if (project == null)
            {
                project = new Project();
            }
            else
            {
                //记录之前的文件
                if (!string.IsNullOrEmpty(project.CertUrl))
                {
                    oldcertUrl = HttpContext.Current.Server.MapPath("~/Certificate/" + project.CertUrl);
                }

                if (!string.IsNullOrEmpty(project.SandBox_CertUrl))
                {
                    oldSandBox_CertUrl = HttpContext.Current.Server.MapPath("~/Certificate/" + project.SandBox_CertUrl);
                }

            }
            project.Identity = model.AppName;
            if (!string.IsNullOrEmpty(certUrl)) //证书如果没有上传的话，不会清除之前的证书
                project.CertUrl = certUrl;

            if (!string.IsNullOrEmpty(sandBox_CertUrl))
                project.SandBox_CertUrl = sandBox_CertUrl;

            project.CertPwd = model.PassWord;
            project.SandBox_CertPwd = model.SandBoxPassWord;
            project.SenderId = model.SenderId;
            project.Token = model.AuthorizationToken;
            project.PackageName = model.PackageName;
            project.IsUseGcm = model.IsUseGcm;
            project.IsUseApns = model.IsUseApns;
            project.IsUseSignalr = model.IsUseSignalr;

            //添加或修改這個項目配置時將判斷配置錯誤的表示設備為false,表示能正常使用了
            project.ApnsError = false;
            project.GcmError = false;

            AddOrUpdate(project);
            //throw new Exception(); //这种情况下，应该不会删除之前的文件了，因为持久化到数据库错了，所以其实不需要事务，因为这种简单的事务本身对文件的操作不起作用，最明智的做法还是将文件操作放到数据库操作之后即可

            //最后保存成功之后再删除之前上传的文件
            if (File.Exists(oldSandBox_CertUrl))
            {
                File.Delete(oldSandBox_CertUrl);
            }
            if (File.Exists(oldcertUrl))
            {
                File.Delete(oldcertUrl);
            }

            //LogHelper.WriteInfoLog(string.Format("證書地址:{0}\r\n{1}", oldSandBox_CertUrl, oldcertUrl));
        }

        public static List<Project> GetList(GetProjectListModel model)
        {
            return GetListNoTrack();
        }

        private static string SaveFile(string requestFileName, HttpRequest request, HttpServerUtility server, string appName)
        {
            string fileName = string.Empty;
            //取到文件对象
            var file = request.Files[requestFileName];
            if (file != null)
            {
                //判断上传文件的类型，这里是根据文件头判断的，防止用户上传恶意假图
                if (file.ContentType == "application/x-pkcs12")
                {
                    //给文件取随及名
                    try
                    {
                        Random ran = new Random();
                        fileName = GetFileName(appName + requestFileName); //因为是同时上传的，只是用时间的话可能会导致两个文件名称相同而覆盖，所以加上requestfilename来区分正式和测试证书文件
                        var serverPath = server.MapPath("~/Certificate/");
                        if (!Directory.Exists(serverPath))
                            Directory.CreateDirectory(serverPath);

                        //保存文件
                        var path = serverPath + fileName;
                        file.SaveAs(path);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("上傳文件失敗！");
                    }
                }
                else
                {
                    throw new Exception("文件格式錯誤！");
                }
            }
            return fileName;
        }

        public static string GetFileName(string appName)
        {
            if (string.IsNullOrEmpty(appName)) return string.Empty;
            string value = appName;

            Regex reg = new Regex(@"([a-zA-Z0-9])");
            StringBuilder sb = new StringBuilder();
            foreach (var item in value.ToCharArray())
            {
                string s = item.ToString();
                var match = reg.Match(s);
                if (match.Success)
                {
                    sb.Append(s);
                }
            }
            sb.AppendFormat("_{0}", DateTime.Now.ToString("yyyymmddHHmmssff"));
            sb.Append(".p12");
            return sb.ToString();

        }
    }
}
